
// <copyright file="DataReaderDataTableAdapter.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The data reader data table adapter.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data
{
    using System;
    using System.Data;

    /// <summary>
    /// The data reader data table adapter.
    /// </summary>
    public class DataReaderDataTableAdapter
    {
        #region Fields

        /// <summary>
        /// The name.
        /// </summary>
        private readonly string name;

        /// <summary>
        /// The reader.
        /// </summary>
        private readonly IDataReader reader;

        /// <summary>
        /// The table.
        /// </summary>
        private readonly DataTable table;

        /// <summary>
        /// The row index.
        /// </summary>
        private int rowIndex = -1;

        #endregion Fields

        #region Constructors and Finalizers

        /// <summary>
        /// Initializes a new instance of the <see cref="DataReaderDataTableAdapter"/> class.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        public DataReaderDataTableAdapter(IDataReader reader, string name)
        {
            this.reader = reader;
            this.name = name;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DataReaderDataTableAdapter"/> class.
        /// </summary>
        /// <param name="table">
        /// The table.
        /// </param>
        public DataReaderDataTableAdapter(DataTable table)
        {
            this.table = table;
        }

        #endregion Constructors and Finalizers

        #region Public Properties

        /// <summary>
        /// Gets the column count.
        /// </summary>
        public int ColumnCount
        {
            get
            {
                return this.reader == null ? this.table.Columns.Count : this.reader.FieldCount;
            }
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        public string Name
        {
            get
            {
                return this.reader == null ? this.table.TableName : this.name;
            }
        }

        #endregion Public Properties

        #region Public Methods and Operators

        /// <summary>
        /// The get column name.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetColumnName(int i)
        {
            return this.reader == null ? this.table.Columns[i].ColumnName : this.reader.GetName(i);
        }

        /// <summary>
        /// The get column type.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="Type"/>.
        /// </returns>
        public Type GetColumnType(int i)
        {
            return this.reader == null ? this.table.Columns[i].DataType : this.reader.GetFieldType(i);
        }

        /// <summary>
        /// The get value.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object GetValue(int i)
        {
            return this.reader == null ? this.table.Rows[this.rowIndex][i] : this.reader[i];
        }

        /// <summary>
        /// The read.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool Read()
        {
            if (this.reader != null)
            {
                bool canRead = this.reader.Read();
                if (!canRead)
                {
                    this.reader.Dispose();
                }

                return canRead;
            }

            this.rowIndex++;
            return this.rowIndex < this.table.Rows.Count;
        }

        #endregion Public Methods and Operators
    }
}